package com.founder.bdyx.wxpro.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.founder.bdyx.PdfReport;
import com.founder.bdyx.core.util.SpringContextHolder;
import com.founder.bdyx.modules.sys.model.UserInfo;
import com.founder.bdyx.modules.sys.service.UserInfoService;
import com.founder.bdyx.wxpro.aes.AesException;
import com.founder.bdyx.wxpro.aes.WXBizMsgCrypt;
import com.founder.bdyx.wxpro.conf.WxConfig;
import com.founder.bdyx.wxpro.model.InMsgEntity;
import com.founder.bdyx.wxpro.util.HttpUtil;
import com.founder.bdyx.wxpro.util.VerifyUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import javax.servlet.ServletContext;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/wxpro")
public class WxController {
    Logger log = LoggerFactory.getLogger(WxController.class);

    @Autowired
    private WxConfig wxConfig;
    @Autowired
    private UserInfoService userInfoService;

    /**
     * 服务器配置 验证路径
     * @param signature
     * @param timestamp
     * @param nonce
     * @param echostr
     * @return
     */
    @RequestMapping(value = "/getecho",method = RequestMethod.GET)
    public String getEcho(String signature, String timestamp, String nonce, String echostr) throws AesException {
        log.info("signature : " + signature);
        log.info("timestamp : " + timestamp);
        log.info("nonce : " + nonce);
        log.info("echostr : " + echostr);

        WXBizMsgCrypt crypt = new WXBizMsgCrypt(wxConfig.token, wxConfig.encodingAESKey, wxConfig.appId);
        String result = crypt.checkToken(signature, timestamp, nonce, echostr);
        return result;
    }

    /**
     * 用于接收处理微信消息和事件
     * @param inMsgEntity 封装的xml入参对象
     * 参数格式
     * <xml>
     *   <ToUserName><![CDATA[toUser]]></ToUserName>
     *   <FromUserName><![CDATA[FromUser]]></FromUserName>
     *   <CreateTime>123456789</CreateTime>
     *   <MsgType><![CDATA[event]]></MsgType>
     *   <Event><![CDATA[subscribe]]></Event>
     * </xml>
     * @return
     * @throws AesException
     * @throws IOException
     */
    @RequestMapping(value = "/getecho",method = RequestMethod.POST)
    public String handleMessage(@RequestBody InMsgEntity inMsgEntity) throws AesException, IOException {

        log.debug("inMsgEntity:" + inMsgEntity);
        if("subscribe".equals(inMsgEntity.getEvent())){//订阅公众号事件
            String openid = inMsgEntity.getFromUserName();
            String accessToken = VerifyUtil.getAccessToken(SpringContextHolder.getServletContext());
            String url = wxConfig.userInfoUrl.replace("ACCESS_TOKEN",accessToken).replace("OPENID",openid);
            String retStr = HttpUtil.sendGet(url);
            JSONObject userjson = JSON.parseObject(retStr);
            UserInfo userInfo = JSONObject.toJavaObject(userjson,UserInfo.class);
            int num = userInfoService.saveOrUpdateUser(userInfo);

            if(num<=0){
                log.info("关注用户：" + openid + ", 保存数据失败");
            }
        }
        if("unsubscribe".equals(inMsgEntity.getEvent())){//取消订阅事件
            String openid = inMsgEntity.getFromUserName();
            int num = userInfoService.delUserByUuid(openid);
            if(num<=0){
                log.info("删除已关注用户：" + openid + ", 的数据失败");
            }
        }
        return "跳转登录首页";
    }

    /**
     * 公众号按钮跳转页面 统一入口
     * @param index
     * @return
     */
    @RequestMapping("/redirect")
    public ModelAndView redirect(String index){
        if(index == null){
            Map<String,String> map = new HashMap<>();
            map.put("msg","error argument");
            return new ModelAndView("wx/error",map);
        }
        String authorize1Url = wxConfig.authorize1Url;
        authorize1Url = authorize1Url
                .replace("APPID",wxConfig.appId)
                .replace("REDIRECT_URI",wxConfig.basePath+"/wxpro/getUserInfo")
                .replace("SCOPE","snsapi_base")
                .replace("STATE",index);

        return new ModelAndView(new RedirectView(authorize1Url));
    }

    @RequestMapping("/getUserInfo")
    public ModelAndView getUserInfo(HttpServletRequest request){
        String code = request.getParameter("code");
        String state = request.getParameter("state");
        log.info("code:" + code + ", state:" + state);
        String appId = wxConfig.appId;
        String appSecret = wxConfig.appSecret;
        String url = wxConfig.authorize2Url;

        /*第二步：通过code换取网页授权access_token*/
        url = url.replace("APPID",appId).replace("SECRET",appSecret).replace("CODE",code);
        String ret = HttpUtil.sendGet(url);
        JSONObject jsonObject = JSON.parseObject(ret);
        String access_token_user = jsonObject.getString("access_token");
        String openid = jsonObject.getString("openid");

        UserInfo userInfo = userInfoService.getByUuid(openid);
        if (userInfo == null){
            Map<String,String> map = new HashMap<>();
            map.put("msg","该用户尚未关注公众号，请关注后再访问");
            return new ModelAndView("wx/error",map);
        }

        /*第三步：刷新access_token（如果需要）  暂不需要
            获取第二步的refresh_token后，
            请求以下链接获取access_token：
            https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN*/

        /*第四步：拉取用户信息(需scope为 snsapi_userinfo)*/
//        url = wxConfig.authorize4Url;
//        url = url.replace("ACCESS_TOKEN",access_token_user).replace("OPENID",openid);
//        String userInfoStr = HttpUtil.sendGet(url);
//        JSONObject userjson = JSON.parseObject(userInfoStr);
//
//        UserInfo userInfo = JSONObject.toJavaObject(userjson,UserInfo.class);
//        userInfoService.saveOrUpdateUser(userInfo);

        String retUrl = "";
        if(state.length()>1){//跳转申请详情页 index=4+uuid
            retUrl = VerifyUtil.getApplyDetail(openid,state.substring(0,1),state.substring(1,state.length()));
        }else{//跳转申请页index=2、申请列表页index=3
            retUrl = VerifyUtil.getLoginToken(openid,state);
        }
        return new ModelAndView(new RedirectView(retUrl));
//        return "<script>window.location.href='"+retUrl+"'</script>";
    }

    /**
     * 病案介绍静态页面
     * @return
     */
    @RequestMapping("/describe")
    public ModelAndView describe(){
        return new ModelAndView("wx/describe");
    }

    /**
     *  自定义菜单 创建接口按钮
     * @return
     */
    @RequestMapping("/createButton")
    public String createButton(HttpServletRequest request) throws IOException {
        String access_token = VerifyUtil.getAccessToken(request.getServletContext());
//        String url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + access_token;
        String url = wxConfig.createButtonUrl;
        url = url.replace("ACCESS_TOKEN",access_token);
        String basePath = wxConfig.basePath;
        String data = "{" +
                "     \"button\":[" +
                "     {" +
                "          \"type\":\"view\"," +
                "          \"name\":\"病案申请\"," +
                "          \"url\":\""+basePath+"/wxpro/redirect?index=2\"" +
                "      }," +
                "      {" +
                "           \"type\":\"view\"," +
                "           \"name\":\"病案介绍\"," +
                "           \"url\":\""+basePath+"/wxgzh/payTest\"" +
                "       }," +
                "       {" +
                "           \"type\":\"view\"," +
                "           \"name\":\"我的申请\"," +
                "           \"url\":\""+basePath+"/wxpro/redirect?index=3\"" +
                "       }]" +
                " }";

        String ret = HttpUtil.sendPost(url, data);
        return ret;
    }

    /**
     *  自定义菜单 删除接口
     * @return
     */
    @RequestMapping("/delButton")
    public String delButton(HttpServletRequest request) throws IOException {
        String access_token = VerifyUtil.getAccessToken(request.getServletContext());
//        String url = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=" + access_token;
        String url = wxConfig.delButtonUrl;
        url = url.replace("ACCESS_TOKEN",access_token);
        String ret = HttpUtil.sendGet(url);
        return ret;
    }
}
